import os
import logging
import uuid
from typing import List, Dict, Any, Optional
from moviepy.video.io.VideoFileClip import VideoFileClip

# 导入工具函数
from utils.download_utils import is_url, download_video, cleanup_downloaded_file
from utils.oss_utils import get_oss_uploader

# 配置日志
logger = logging.getLogger(__name__)


def cut_processor(
    video_url: str,
    cut_time: List[Dict[str, Any]],
    task_id: Optional[str] = None,
    oss_bucket_dir: str = "freefishpc/cloud_video/dispose"
) -> List[Dict[str, Any]]:
    """
    视频剪切处理器，根据提供的时间数组剪切视频并上传到OSS
    
    Args:
        video_url: 视频文件URL或本地路径
        cut_time: 剪切时间数组，格式为[{"start_time":0,"end_time":124},{"start_time":124,"end_time":324}]
        task_id: 任务ID，用于生成唯一的输出文件名
        oss_bucket_dir: OSS存储桶中的目录路径
        
    Returns:
        List[Dict[str, Any]]: 包含剪切时间信息和上传后URL的数组
    """
    logger.info(f"开始处理视频剪切，视频URL: {video_url}")
    logger.info(f"剪切时间数组: {cut_time}")
    
    # 使用项目目录下的download文件夹
    project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    download_dir = os.path.join(project_dir, "download")
    output_dir = os.path.join(project_dir, "output")
    
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    
    # 下载视频文件（如果是URL）
    local_video_path = video_url
    downloaded_file = None
    if is_url(video_url):
        logger.info(f"检测到网络链接，开始下载视频: {video_url}")
        try:
            local_video_path = download_video(video_url, download_dir)
            downloaded_file = local_video_path
            logger.info(f"视频下载完成: {video_url} -> {local_video_path}")
        except Exception as e:
            logger.error(f"下载视频失败: {video_url} - {e}")
            raise
    
    try:
        # 加载视频
        logger.info(f"加载视频: {local_video_path}")
        video_clip = VideoFileClip(local_video_path)
        logger.info(f"视频加载完成，时长: {video_clip.duration} 秒, 尺寸: {video_clip.size}, 帧率: {video_clip.fps}")
        
        # 初始化结果数组
        result = []
        
        # 获取OSS上传器
        oss_uploader = get_oss_uploader()
        if not oss_uploader:
            logger.warning("无法创建OSS上传器，将返回本地文件路径")
        
        # 循环处理每个剪切时间段
        for i, time_info in enumerate(cut_time):
            start_time = time_info.get("start_time", 0)
            end_time = time_info.get("end_time", 0)
            
            logger.info(f"处理第 {i+1} 个剪切段: {start_time}s - {end_time}s")
            
            try:
                # 剪切视频片段
                subclip = video_clip.subclipped(start_time, end_time)
                
                # 生成输出文件名
                if task_id:
                    output_filename = f"{task_id}_cut_{i+1}.mp4"
                else:
                    # 如果没有提供task_id，使用随机ID
                    random_id = str(uuid.uuid4())[:8]
                    output_filename = f"{random_id}_cut_{i+1}.mp4"
                
                output_path = os.path.join(output_dir, output_filename)
                
                # 导出剪切后的视频
                logger.info(f"导出剪切视频到: {output_path}")
                subclip.write_videofile(
                    output_path,
                    codec="libx264",
                    audio_codec="aac",
                    temp_audiofile=os.path.join(output_dir, f"temp_audio_{i+1}.m4a"),
                    remove_temp=True,
                    verbose=False,
                    logger=None
                )
                
                # 关闭子剪辑
                subclip.close()
                
                # 上传到OSS
                final_url = output_path  # 默认为本地路径
                if oss_uploader:
                    try:
                        # 生成OSS对象键
                        oss_object_key = f"{oss_bucket_dir}/{output_filename}"
                        # 上传文件到OSS
                        oss_url = oss_uploader.upload_file(output_path, oss_object_key)
                        final_url = oss_url
                        logger.info(f"视频片段已上传到OSS: {oss_url}")
                        
                        # 删除本地文件以节省空间
                        try:
                            os.remove(output_path)
                            logger.info(f"已删除本地文件: {output_path}")
                        except Exception as e:
                            logger.warning(f"删除本地文件失败 {output_path}: {e}")
                    except Exception as e:
                        logger.error(f"上传视频到OSS失败: {e}")
                        # 保持本地路径
                
                # 添加到结果数组
                result_item = time_info.copy()
                result_item["url"] = final_url
                result.append(result_item)
                
            except Exception as e:
                logger.error(f"处理剪切段失败 {i+1} ({start_time}s - {end_time}s): {e}")
                # 添加错误信息到结果
                result_item = time_info.copy()
                result_item["url"] = None
                result_item["error"] = str(e)
                result.append(result_item)
                continue
        
        # 关闭视频剪辑
        video_clip.close()
        
        # 清理下载的文件
        cleanup_downloaded_file(downloaded_file)
        
        logger.info("视频剪切处理完成")
        return result
        
    except Exception as e:
        # 清理下载的文件
        cleanup_downloaded_file(downloaded_file)
        
        logger.error(f"处理视频时发生错误: {e}")
        raise